import { Injectable } from "@nestjs/common";
import { Cron, CronExpression, SchedulerRegistry } from "@nestjs/schedule";
import { CronJob } from "cron";
import { LoggerService } from "../logger/logger.service";
import { DateTime, Interval, Settings } from 'luxon';

// 在服务类顶部添加时区常量
const FRONTEND_TIMEZONE = 'Asia/Shanghai'; // 对应中文环境
const BACKEND_TIMEZONE = 'UTC';

@Injectable()
export class TaskService {

  constructor(
    private readonly schedulerRegistry: SchedulerRegistry,
    private readonly logger: LoggerService

  ) {
    this.logger.setContext(TaskService.name)
  }

  private recordJobsMap = new Map<string, string[]>(); // 格式: { recordId: [jobName1, jobName2] }


  /**
  * 生成所有执行日期
  */
  private generateExecutionDates(
    startDate: string,
    sendDays: number,
    interval: number,
  ): DateTime[] {

    const start = DateTime.fromISO(startDate, { zone: FRONTEND_TIMEZONE }).toUTC();
    const dates: DateTime[] = [];

    for (let i = 0; i < sendDays; i += interval + 1) {
      const date = start.plus({ days: i });
      dates.push(date);
    }
    return dates;
  }

  /**
  * 生成所有执行时间点
  */
  private generateExecutionTimes(dates: DateTime[], times: string[]): DateTime[] {

    return dates.flatMap((date) =>
      times.map((timeStr) => {
        // 解析前端时间为中国时区，再转换为UTC
        const [hour, minute] = timeStr.split(':').map(Number);
        return DateTime.fromObject(
          {
            year: date.year,
            month: date.month,
            day: date.day,
            hour,
            minute,
          },
          { zone: FRONTEND_TIMEZONE }
        ).toUTC();
      }),
    );
  }

  /**
   * 转换日期为 Cron 表达式
   */
  private getCronExpression(date: DateTime): string {
    const utcDate = date.setZone(BACKEND_TIMEZONE);
    console.log('打印***`${utcDate.minute} ${utcDate.hour} ${utcDate.day} ${utcDate.month} *`', `${utcDate.minute} ${utcDate.hour} ${utcDate.day} ${utcDate.month} *`)
    return `${utcDate.minute} ${utcDate.hour} ${utcDate.day} ${utcDate.month} *`;
  }


  /**
  * 执行任务逻辑
  */
  private executeTask(execTime: string, jobName: string) {
    this.logger.log(`执行任务: ${jobName} @ ${execTime}`);
    // 这里编写实际业务逻辑
    console.log('打印***111', 111)
    // 任务完成后删除（可选）
    this.schedulerRegistry.deleteCronJob(jobName);
  }


  /**
 * 添加或更新记录的任务
 * @param recordId 记录唯一ID
 * @param startDate 开始日期（如 '2025-03-06'）
 * @param sendDays 发送总天数（如 10）
 * @param interval 间隔天数（如 1）
 * @param times 时间点（如 ['08:00', '14:00', '22:00']）
 */
  async upsertRecordTasks(
    recordId: string,
    startDate: string,
    sendDays: number,
    interval: number,
    times: string[],
  ) {
    // 1. 删除旧任务（如果存在）
    await this.deleteRecordTasks(recordId);

    // 2. 生成新任务
    const executionDates = this.generateExecutionDates(startDate, sendDays, interval);
    const executionTimes = this.generateExecutionTimes(executionDates, times);
    const jobNames: string[] = [];


    executionTimes.forEach((execTime, index) => {
      const jobName = `job-${recordId}-${index}`; // 唯一任务名称
      const cronExpression = this.getCronExpression(execTime);

      const job = new CronJob(
        cronExpression,
        () => {
          this.executeTask(execTime.toISO(), jobName);
        },
        null,
        true,
        'UTC',
      );

      this.schedulerRegistry.addCronJob(jobName, job);
      this.logger.log(`任务已注册: ${jobName} @ ${execTime.toISO()}`);

      job.start();
      jobNames.push(jobName);
    });

    // 3. 更新记录关联的任务名称
    this.recordJobsMap.set(recordId, jobNames);
  }

  /**
 * 删除记录关联的所有任务
 * @param recordId 记录ID
 */
  async deleteRecordTasks(recordId: string) {

    const jobNames = this.recordJobsMap.get(recordId) || [];

    jobNames.forEach(jobName => {
      if (this.schedulerRegistry.doesExist('cron', jobName)) {
        this.schedulerRegistry.deleteCronJob(jobName);
        this.logger.log(`任务已删除: ${jobName}`);
      }
    });

    // 清理Map中的数据
    this.recordJobsMap.delete(recordId);
  }

}
